/*
 * Copyright © 2017 eqxiu.com 北京中网易企秀科技有限公司  All rights reserved.
 */
package cn.hermit.data.json.validator;

import cn.hermit.data.exception.ValidationException;
import cn.hermit.data.json.JSON;
import cn.hermit.data.json.JSONChar;
import cn.hermit.util.StringUtils;

/**
 * Default validator for basic JSON string validation.
 * 
 * @author Jack Gao (Chinese name : GAO JIANGUO, Email : linux.gjg@gmail.com)
 * @date 18 Jun, 2014
 */
public class DefaultValidator implements Validator {

	/**
	 * Indicate if the forward slashes need to be escaped.
	 */
	protected boolean forwardSlashEscaping;

	/**
	 * Indicate if keep null key or value for JSON string.
	 */
	protected boolean keepNull = true;

	@Override
	public String validateKey(String key) throws ValidationException {
		if (key == null) {
			if (keepNull) {
				return JSON.DEFAULT_NULL_VALUE;
			}
		}
		if (StringUtils.isEmpty(key, false)) {
			throw new ValidationException("Invalid JSON KEY");
		}
		return JSONChar.escape(key, forwardSlashEscaping);
	}

	@Override
	public Object validateValue(Object value) throws ValidationException {
		if (value == null) {
			if (keepNull) {
				return null;
			} else {
				return JSON.DEFAULT_EMPTY_VALUE;
			}
		}
		if (String.class.isInstance(value)) {
			return JSONChar.escape(value.toString(), forwardSlashEscaping,hasPartEscaping);
		}
		return value;
	}

	/**
	 * @return 
	 * 		if keep null key or value for JSON string
	 */
	public boolean isKeepNull() {
		return keepNull;
	}

	/**
	 * @param keepNull
	 * 		<p>
	 * 		If true, will keep null key and convert null value to "null".
	 * 		Otherwise, will throw ValidationException if key is null, and convert
	 * 		null value to {@link JSON#DEFAULT_EMPTY_VALUE default empty value}.
	 * 		</p>
	 */
	public void setKeepNull(boolean keepNull) {
		this.keepNull = keepNull;
	}

	/**
	 * @return 
	 * 		if the forward slashes need to be escaped
	 */
	public boolean isForwardSlashEscaping() {
		return forwardSlashEscaping;
	}

	/**
	 * @param forwardSlashEscaping
	 * 		Switch for forward slash "/" escaping
	 * 		<p>
	 * 		 If true, will escape forward slashes {@code // => \/\/}.
	 *       Otherwise, will escape forward slashes {@code // => //}
	 *       </p>
	 */
	public void setForwardSlashEscaping(boolean forwardSlashEscaping) {
		this.forwardSlashEscaping = forwardSlashEscaping;
	}
	
	private boolean hasPartEscaping = true;

	public boolean hasPartEscaping() {
		return hasPartEscaping;
	}

	public void setHasPartEscaping(boolean hasPartEscaping) {
		this.hasPartEscaping = hasPartEscaping;
	}
	
}